#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/miscdevice.h>
#include <linux/fs.h>

#include <mach/iomap.h>
#include <mach/io.h>

//#include <linux/uaccess.h>
//#include <linux/delay.h>
//#include <linux/sched.h>
//#include <linux/kthread.h>

//#define NX_DEBUG

#include "module/nx_gpio.h"

#define DEVICE_NAME					"ati2c"
/*
static const U32 BaseAddress[NUMBER_OF_GPIO_MODULE] = {
	0xC001A000,
	0xC001B000,
	0xC001C000,
	0xC001D000,
	0xC001E000,
};
*/
static int ati2c_open(struct inode *inode, struct file *flip)
{
	return 0;
}

static long ati2c_ioctl(struct file *flip, unsigned int cmd, unsigned long arg)
{
	return -EINVAL;
}

static int ati2c_close(struct inode *inode, struct file *flip)
{
	return 0;
}

static struct file_operations ati2c_fops = {
	.owner			=	THIS_MODULE,
	.open			=	ati2c_open,
	.unlocked_ioctl	=	ati2c_ioctl,
	.release		=	ati2c_close,
};

static struct miscdevice misc = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = DEVICE_NAME,
	.fops = &ati2c_fops,
};

static int __init ati2c_init(void)
{
	int i = 0;

	if(0 == misc_register(&misc))
	{
		NX_GPIO_Initialize();
		for (i = 0; NX_GPIO_GetNumberOfModule() > i; i++) {
			NX_GPIO_SetBaseAddress(i, (U32)IO_ADDRESS(NX_GPIO_GetPhysicalAddress(i)));
			NX_GPIO_OpenModule(i);
		}

		NX_GPIO_SetPadFunction(3, 4, NX_GPIO_PADFUNC_0);
		NX_GPIO_SetOutputEnable(3, 4, CTRUE);
		NX_GPIO_SetOutputValue(3, 4, CTRUE);
	
		NX_GPIO_SetPadFunction(3, 5, NX_GPIO_PADFUNC_0);
		NX_GPIO_SetOutputEnable(3, 5, CTRUE);
		NX_GPIO_SetOutputValue(3, 5, CTRUE);

		printk(KERN_INFO "%s\n", CTRUE == NX_GPIO_GetOutputValue(3, 4) ? "High" : "Low");
		printk(KERN_INFO "%s\n", CTRUE == NX_GPIO_GetOutputValue(3, 5) ? "High" : "Low");

		return 0;
	}
	return -ENOMEM;
}

static void __exit ati2c_exit(void)
{
	misc_deregister(&misc);
}

MODULE_AUTHOR("Yan Jun");
MODULE_DESCRIPTION("ati2c gpio test");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ati2c");

module_init(ati2c_init);
module_exit(ati2c_exit);
